
package com.joysuch.wwyt.datadump.controller;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import cn.afterturn.easypoi.excel.export.ExcelExportService;
import cn.zlg.common.datadump.bean.BatchDeleteResult;
import cn.zlg.common.datadump.bean.ExportConfig;
import cn.zlg.common.datadump.bean.ImportResult;
import cn.zlg.common.datadump.bean.MultiExportConfig;
import cn.zlg.common.datadump.enums.ImportDuplicateProcess;
import cn.zlg.common.datadump.service.DataDumpService;
import cn.zlg.common.datadump.util.HttpServletRequestWrapperWithPrefix;
import cn.zlg.common.util.CollectionUtils;
import com.google.gson.Gson;
import com.joysuch.wwyt.core.common.ajax.ResultBean;
import com.joysuch.wwyt.core.enums.Status;
import com.joysuch.wwyt.datadump.biz.model.BpProductFacilityDumpBean;
import com.joysuch.wwyt.datadump.biz.model.RiskDistrictDumpBean;
import com.joysuch.wwyt.risk.repository.RiskEvaluationControlDao;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

import static cn.afterturn.easypoi.excel.ExcelExportUtil.USE_SXSSF_LIMIT;

@Controller
@RequestMapping("/data-dump")
public class DataDumpController {

    @Autowired
    private DataDumpService dataDumpService;
    @Autowired
    private RiskEvaluationControlDao controlDao;

    @RequestMapping("import")
    @ResponseBody
    public Object doImport(MultipartFile file, String handler, @RequestParam(defaultValue = "true") boolean override, @RequestParam(defaultValue = "0") Integer sheetIndex,
                           @RequestParam(defaultValue = "1") Integer headRows, @RequestParam(defaultValue = "0") Integer titleRows, HttpServletRequest request, HttpServletResponse response) {
        try {
            if (!file.getOriginalFilename().endsWith("xlsx") && !file.getOriginalFilename().endsWith("xls")) {
                return ResultBean.fail(500, "文件类型不正确");
            }
            ImportDuplicateProcess duplicateProcess = override ? ImportDuplicateProcess.OVERRIDE : ImportDuplicateProcess.SKIP;
            ImportResult importResult = dataDumpService.doImport(handler, file, sheetIndex, titleRows, headRows, duplicateProcess, request);
            return ResultBean.success(importResult);
        } catch (Exception e) {
            e.printStackTrace();
            return ResultBean.fail(500, e.getMessage());
        }
    }

    @RequestMapping("batch-delete")
    @ResponseBody
    public Object batchDelete(String handler, HttpServletRequest request, HttpServletResponse response) {
        try {
            BatchDeleteResult r = dataDumpService.batchDelete(handler, request);
            if (r.getCode() == Status.DELETE_CHECK_FAILED.getCode()) {
                return ResultBean.fail(Status.DELETE_CHECK_FAILED.getCode(), "", r);
            } else {
                return ResultBean.success(r);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return ResultBean.fail(500, e.getMessage());
        }
    }

    @RequestMapping("export")
    public void export(String handler, HttpServletRequest request, HttpServletResponse response) {
        try {
            List list = dataDumpService.doExport(handler, request);
            convertData(handler, list);
            String dynamicDataBizType = dataDumpService.getDynamicDataBizType(handler);
            Workbook workbook;
            String templateName = dataDumpService.getBusinessName(handler);

            list = (List) list.stream().filter(Objects::nonNull).collect(Collectors.toList());
            if (StringUtils.isNotBlank(dynamicDataBizType)) {
                workbook = dataDumpService.createDynamicExcel(list, handler, dynamicDataBizType);
            } else {
                workbook = ExcelExportUtil.exportExcel(new ExportParams(null, "数据"), dataDumpService.getEntityClass(handler), list);
            }
            outputExcel(workbook, templateName, request, response);
        } catch (Exception e) {
            e.printStackTrace();
            response.setCharacterEncoding("utf-8");
            response.setStatus(500);
            try {
                response.getWriter().append(e.getMessage());
                response.flushBuffer();
            } catch (IOException e1) {
                e1.printStackTrace();
            }
        }
    }

    private void convertData(String handler, List list) {
        if (CollectionUtils.isEmpty(list)) {
            return;
        }
        if (handler.equals("risk-district-dump") && !CollectionUtils.isEmpty(list)) {
            List<RiskDistrictDumpBean> districtList = list;
            districtList.forEach((e) -> {
                e.setRiskLevelName(e.getStableRiskLevel());
            });
        } else if (handler.equals("bp-product-facility-dump")) {
            List<BpProductFacilityDumpBean> facilityList = list;
            Iterator<BpProductFacilityDumpBean> iterator = facilityList.iterator();
            while (iterator.hasNext()) {
                BpProductFacilityDumpBean next = iterator.next();
                if (next.getLifecycle() != null && next.getLifecycle().equals("S")) {
                    iterator.remove();
                }
            }
        }
    }

    @RequestMapping("multi-sheet-export")
    public void multiSheetExport(String config, HttpServletRequest request, HttpServletResponse response) {
        try {
            MultiExportConfig mc = new Gson().fromJson(config, MultiExportConfig.class);
            for (ExportConfig c : mc.getConfigs()) {
                HttpServletRequestWrapperWithPrefix req = new HttpServletRequestWrapperWithPrefix(request, c.getParamPrefix());
                List list = dataDumpService.doExport(c.getHandler(), req);
                c.setData(list);
            }
            createExcel(mc, request, response);
        } catch (Exception e) {
            e.printStackTrace();
            response.setCharacterEncoding("utf-8");
            response.setStatus(500);
            try {
                response.getWriter().append(e.getMessage());
                response.flushBuffer();
            } catch (IOException e1) {
                e1.printStackTrace();
            }
        }
    }

    private void createExcel(MultiExportConfig mc, HttpServletRequest request, HttpServletResponse response) {
        try {
            ExportParams params = new ExportParams(null, "数据");
            Workbook workbook = getWorkbook(params.getType(), mc.getConfigs().get(0).getData().size());
            for (ExportConfig c : mc.getConfigs()) {
                ExportParams entity = new ExportParams(null, c.getSheetName() == null ? "数据" : c.getSheetName());
                new ExcelExportService().createSheet(workbook, entity, dataDumpService.getEntityClass(c.getHandler()), c.getData());
            }
            outputExcel(workbook, mc.getFilePrefix() == null ? "导出" : mc.getFilePrefix(), request, response);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static Workbook getWorkbook(ExcelType type, int size) {
        if (ExcelType.HSSF.equals(type)) {
            return new HSSFWorkbook();
        } else if (size < USE_SXSSF_LIMIT) {
            return new XSSFWorkbook();
        } else {
            return new SXSSFWorkbook();
        }
    }

    private void outputExcel(Workbook workbook, String templateName, HttpServletRequest request,
                             HttpServletResponse response) throws UnsupportedEncodingException {

        String agent = request.getHeader("User-Agent");
        // 重置响应对象
        response.reset();
        // 当前日期，用于导出文件名称
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        String dateStr = templateName + "-" + sdf.format(new Date()) + ".xlsx";
        if (workbook instanceof HSSFWorkbook) {
            dateStr = templateName + "-" + sdf.format(new Date()) + ".xls";
        }
        // 指定下载的文件名--设置响应头
        response.setHeader("Content-Disposition", "attachment;filename=" + dateStr);
        // response.setContentType("application/vnd.ms-excel;charset=UTF-8");
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        // response.setHeader("Pragma", "no-cache");
        dateStr = URLEncoder.encode(dateStr, "utf-8");
        if (agent.contains("MSIE")) {
            // IE浏览器
            dateStr = dateStr.replace("+", " ");
        }
        // filename*属性，解决safari浏览器下载文件名显示utf8编码的问题
        response.setHeader("Content-Disposition", "attachment;fileName=" + dateStr + ";filename*=utf-8''" + dateStr);
        // response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);
        // 写出数据输出流到页面
        try {
            OutputStream output = response.getOutputStream();
            BufferedOutputStream bufferedOutPut = new BufferedOutputStream(output);
            workbook.write(bufferedOutPut);
            bufferedOutPut.flush();
            bufferedOutPut.close();
            output.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
